package com.xxxtea.controller;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xxxtea.common.Result;
import com.xxxtea.common.UserContext;
import com.xxxtea.dto.ChatSessionRequest;
import com.xxxtea.dto.ChatUser;
import com.xxxtea.dto.MessageRequest;
import com.xxxtea.entity.*;
import com.xxxtea.mpe.helper.ResourceHelper;
import com.xxxtea.service.*;
import com.xxxtea.ws.WebSocketHandler;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 聊天控制器
 *
 * 提供聊天功能的完整管理，包括：
 * - 聊天会话管理（创建、删除、查询）
 * - 消息发送和接收
 * - 在线用户管理
 * - 消息已读状态管理
 * - WebSocket实时通信
 *
 * 使用Swagger注解进行API文档生成
 *
 * @author badman
 * @since 1.0.0
 */
@Api("聊天接口")
@RestController
@RequestMapping("/chat")
public class ChatController {
	/**
	 * 任务服务
	 */
	@Resource
	private TaskService taskService;
	
	/**
	 * 旧物商品服务
	 */
	@Resource
	private SecondhandGoodsService secondhandGoodsService;
	
	/**
	 * WebSocket处理器
	 */
	@Resource
	private WebSocketHandler webSocketHandler;
	
	/**
	 * 聊天消息服务
	 */
	@Resource
	private ChatMessageService chatMessageService;
	
	/**
	 * 聊天会话服务
	 */
	@Resource
	private ChatSessionService chatSessionService;
	
	/**
	 * 聊天会话关联服务
	 */
	@Resource
	private ChatSessionRelService chatSessionRelService;
	
	/**
	 * 聊天消息已读服务
	 */
	@Resource
	private ChatMessageReadService chatMessageReadService;

	/**
	 * 获取在线用户列表
	 *
	 * @return 在线用户列表
	 */
	@ApiOperation("获取在线用户列表")
	@GetMapping("/listOnlineUsers")
	public Result<List<ChatUser>> listOnlineUsers() {
		return Result.success(new ArrayList<>(webSocketHandler.getUserMap().values()));
	}

	/**
	 * 获取全部聊天会话列表
	 * 包含未读消息数量统计
	 *
	 * @return 聊天会话列表
	 */
	@ApiOperation("获取全部聊天会话列表")
	@GetMapping("/listAllSessions")
	public Result<List<ChatSession>> listAllSessions() {
		// 获取用户未读消息统计
		Map<Integer, Long> readMap = chatMessageReadService.lambdaQuery()
				.eq(ChatMessageRead::getUserId, UserContext.getId())
				.eq(ChatMessageRead::isRead, false)
				.list().stream().collect(Collectors.groupingBy(ChatMessageRead::getSessionId, Collectors.counting()));

		// 获取用户参与的会话ID集合
		Set<Integer> sessionIds = chatSessionRelService.lambdaQuery().eq(ChatSessionRel::getUserId, UserContext.getId())
				.list().stream().map(ChatSessionRel::getSessionId).collect(Collectors.toSet());
		List<ChatSession> chatSessions = chatSessionService.listByIds(sessionIds);
		for (ChatSession chatSession : chatSessions) {
			// 设置未读消息数量
			chatSession.setUnreadCount(NumberUtil.nullToZero(readMap.get(chatSession.getId())));
			// 查询消息记录
			chatSession.setMessageList(chatMessageService.listByIds(chatSession.getMessageIds()));
		}
		return Result.success(chatSessions);
	}

	/**
	 * 获取指定聊天会话详情
	 * 包含消息列表和图片资源处理
	 *
	 * @param id 会话ID
	 * @return 聊天会话详情
	 */
	@ApiOperation("获取聊天会话列表")
	@GetMapping("/listSession/{id}")
	public Result<ChatSession> listSession(@PathVariable Integer id) {
		ChatSession chatSession = chatSessionService.getById(id);
		// 查询消息记录
		chatSession.setMessageList(chatMessageService.listByIds(chatSession.getMessageIds()));
		// 处理图片消息的资源路径
		for (ChatMessage chatMessage : chatSession.getMessageList()) {
			if (chatMessage.getType() == ChatMessage.Type.IMAGE) {
				String content = chatMessage.getContent();
				chatMessage.setContent(ResourceHelper.wrap(content));
			}
		}
		return Result.success(chatSession);
	}

	/**
	 * 创建聊天会话
	 * 支持任务和旧物两种业务类型
	 *
	 * @param request 会话创建请求
	 * @return 会话ID
	 */
	@ApiOperation("创建聊天会话列表")
	@PostMapping("/createSession")
	public Result<Integer> createSession(@RequestBody ChatSessionRequest request) {
		Integer userId = request.getUserId();
		// 检查是否已存在会话
		ChatSession session = chatSessionService.getBaseMapper().findSession(
				UserContext.getId(), userId, request.getBusinessId(), request.getBusinessType());
		if (session != null) {
			return Result.success(session.getId());
		}

		// 根据业务类型生成会话名称
		String name = "";
		if (request.getBusinessType() == 1) {
			Task task = taskService.getById(request.getBusinessId());
			name = StrUtil.format("任务 [{}]", task.getName());
		} else {
			SecondhandGoods secondhandGoods = secondhandGoodsService.getById(request.getBusinessId());
			name = StrUtil.format("旧物 [{}]", secondhandGoods.getName());
		}

		// 创建聊天会话
		ChatSession chatSession = new ChatSession();
		chatSession.setName(name);
		chatSession.setOwnerId(UserContext.getId());
		chatSession.setUserIds(ListUtil.of(userId, UserContext.getId()));
		chatSessionService.save(chatSession);

		// 创建会话关联关系
		ChatSessionRel chatSessionRel = new ChatSessionRel();
		chatSessionRel.setBusinessId(request.getBusinessId());
		chatSessionRel.setBusinessType(request.getBusinessType());
		chatSessionRel.setUserId(UserContext.getId());
		chatSessionRel.setSessionId(chatSession.getId());
		chatSessionRelService.save(chatSessionRel);
		// 为对方用户创建关联关系
		chatSessionRel.setId(null);
		chatSessionRel.setUserId(userId);
		chatSessionRelService.save(chatSessionRel);
		return Result.success(chatSession.getId());
	}

	/**
	 * 删除聊天会话
	 * 同时删除会话关联关系
	 *
	 * @param id 会话ID
	 * @return 操作结果
	 */
	@ApiOperation("删除聊天会话列表")
	@PostMapping("/deleteSession/{id}")
	public Result<Void> deleteSession(@PathVariable Integer id) {
		chatSessionService.removeById(id);
		// 删除会话关联关系
		chatSessionRelService.remove(new LambdaQueryWrapper<>(ChatSessionRel.class)
				.eq(ChatSessionRel::getSessionId, id));
		return Result.success();
	}

	/**
	 * 发送消息
	 * 保存消息并通知在线用户
	 *
	 * @param request 消息请求
	 * @return 操作结果
	 * @throws IOException IO异常
	 */
	@ApiOperation("发送消息")
	@PostMapping("/send")
	public Result<Void> send(@RequestBody MessageRequest request) throws IOException {
		// 构建消息对象
		ChatMessage message = ChatMessage.builder()
				.sessionId(request.getSessionId())
				.senderId(UserContext.getId())
				.type(request.getType())
				.name(UserContext.getUser().getNickname())
				.avatar(UserContext.getUser().getAvatar())
				.content(request.getContent())
				.build();
		chatMessageService.save(message);

		// 更新会话消息ID列表
		ChatSession chatSession = chatSessionService.getById(request.getSessionId());
		chatSession.getMessageIds().add(message.getId());
		chatSessionService.updateById(chatSession);

		// 为会话成员创建消息已读记录
		List<ChatMessageRead> chatMessageReads = chatSession.getUserIds().stream().map(userId -> ChatMessageRead.builder()
				.userId(userId)
				.sessionId(chatSession.getId())
				.messageId(message.getId())
				.read(UserContext.getId().equals(userId)) // 发送者默认已读
				.build()
		).collect(Collectors.toList());
		chatMessageReadService.saveBatch(chatMessageReads);

		// 通过WebSocket通知在线用户
		Map<Integer, WebSocketSession> sessionMap = webSocketHandler.getSessionMap();
		for (Integer userId : chatSession.getUserIds()) {
			WebSocketSession webSocketSession = sessionMap.get(userId);
			// 如果用户在线则发送通知
			if (webSocketSession != null) {
				webSocketSession.sendMessage(new TextMessage("notify"));
			}
		}
		return Result.success();
	}

	/**
	 * 标记会话消息为已读
	 *
	 * @param sessionId 会话ID
	 * @return 操作结果
	 */
	@ApiOperation("阅读信息")
	@PostMapping("/read/{sessionId}")
	public Result<Void> read(@PathVariable Integer sessionId) {
		chatMessageReadService.lambdaUpdate()
				.eq(ChatMessageRead::getSessionId, sessionId)
				.eq(ChatMessageRead::getUserId, UserContext.getId())
				.set(ChatMessageRead::isRead, true)
				.update();
		return Result.success();
	}
}
